package com.ruoyi.common.utils;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.ruoyi.common.constant.CacheConstants;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.Date;

/**
 * @author ruoyi 序列生成类
 */
public class SeqUtil {
    // 通用序列类型
    public static final String COMM_SEQ_TYPE = "COMMON";
    // 上传序列类型
    public static final String UPLOAD_SEQ_TYPE = "UPLOAD";
    // 机器标识
    private static final String MACHINE_CODE = "A";

    private SeqUtil() {
    }

    /**
     * 获取通用序列号
     *
     * @return 序列值
     */
    public static String getId() {
        return getId(COMM_SEQ_TYPE);
    }

    /**
     * 默认16位序列号 yyMMddHHmmss + 一位机器标识 + 4长度每日自增数
     *
     * @return 序列值
     */
    public static String getId(String type) {
        return getId(type, 4);
    }

    /**
     * 通用接口序列号 yyMMddHHmmss + 一位机器标识 + length长度每日自增数
     *
     * @param type   序列数
     * @param length 数值长度
     * @return 序列值
     */
    public static String getId(String type, int length) {
        String result = DateUtil.format(new Date(), DatePattern.PURE_DATETIME_FORMAT);
        result += MACHINE_CODE;
        result += getSeq(type, length);
        return result;
    }

    /**
     * 序列循环递增字符串[1, 10 的 (length)幂次方), 用0左补齐length位数
     *
     * @return 序列值
     */
    private static String getSeq(String type, int length) {
        // 用redis
        BoundValueOperations<String, Long> ops = SpringUtil.getBean(RedisTemplate.class).boundValueOps(CacheConstants.SEQ_INCR_KEY + type);
        Long value = ops.increment();
        ops.expireAt(DateUtil.endOfDay(new Date()));

        // 转字符串，用0左补齐
        return StrUtil.padPre(String.valueOf(value), length, '0');
    }
}
